# 函数的嵌套:在一个函数体内定义另一个函数
# 函数嵌套的作用:
# 1.保证内部函数的隐私,减少函数的作用域
# 2.通过合理的嵌套,能够提升函数的执行效率,比如在实现递归函数时,一些通用的校验可以放在外层函数,把核心的递归逻辑放在内层函数
def outer_func():
    print('outer function')

    # 定义嵌套函数
    def inner_func():
        print('inner function')

    # 调用嵌套函数
    inner_func()


# 外层函数:链接数据库
def connect_db():
    # 内存函数:获取数据库连接
    # 通过嵌套函数的方式,可以保证函数的隐私性,避免外部调用者获取到数据库的配置
    def get_db_config():
        url = 'url'
        username = 'username'
        password = 'password'
        return url, username, password

    config = get_db_config()
    print(f'connect db by config: {config}')


# 外层函数:利用递归实现实现阶乘
def factorial(n):
    # 把一些通用的校验逻辑放在外层函数,避免每次递归处理时都执行该逻辑,可以有效提升函数的执行效率
    if not isinstance(n, int):
        raise Exception('input must by an integer!')

    if n < 0:
        raise Exception('input must by be positive!')

    # 定义内部函数,执行核心递归逻辑
    def inner_factorial(x):
        if x <= 1:
            return 1
        return x * inner_factorial(x - 1)

    # 递归调用,返回结果
    return inner_factorial(n)


if __name__ == '__main__':
    # outer_func()

    # 主程序只能调用外部函数,无法直接调用内部函数
    # connect_db()

    fac = factorial(5)
    print(f'result of factorial is: {fac}')
